package me.seu.demo.thread.future;

import java.util.Random;
import java.util.concurrent.*;

/**
 * 模拟异步线程
 *
 * @author liangfeihu
 * @since 2021/9/1 15:07
 */
public class AsyncThreadHandler {

    private final static ArrayBlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(9);

    private final static RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();

    private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(16, 16, 1000, TimeUnit.MILLISECONDS,
            WORK_QUEUE, HANDLER);


    public static void main2(String[] args) throws Exception {
        long start = System.currentTimeMillis();

        // 任务1: 10s
        Future<Boolean> booleanTask = executorService.submit(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                Thread.sleep(2000);
                return true;
            }
        });

        // 任务2: 3s
        Future<String> stringTask = executorService.submit(new Callable<String>() {

            @Override
            public String call() throws Exception {
                Thread.sleep(3000);
                return "Hello World";
            }
        });

        // 任务3: 2s
        Future<Integer> integerTask = executorService.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                Thread.sleep(6000);
                return new Random().nextInt(100);
            }
        });

        System.out.println("start wait------");

        Boolean result = booleanTask.get();
        String result2 = stringTask.get();
        Integer result3 = integerTask.get();

        System.err.println("任务1---2s：result=" + result);
        System.err.println("任务2---3s：result=" + result2);
        System.err.println("任务3---6s：result=" + result3);

        // 执行时间
        System.out.println("Cost time: " + (System.currentTimeMillis() - start) + " ms!");

        executorService.shutdown();

    }

    public static void main(String[] args) {

        long startTime = System.currentTimeMillis();

        Future<String> future1 = executorService.submit(() -> {
            hello1();
            return "hello world";
        });
        Future<Boolean> future2 = executorService.submit(() -> {
            hello2();
            return Boolean.TRUE;
        });
        Future<Integer> future3 = executorService.submit(() -> {
            hello3();
            return 12;
        });

        try {
            String result = future1.get();
            Boolean result2 = future2.get();
            Integer result3 = future3.get();

            System.err.println("任务1---1s：result=" + result);
            System.err.println("任务2---2s：result=" + result2);
            System.err.println("任务3---3s：result=" + result3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        long endTime = System.currentTimeMillis();

        long costTime = endTime - startTime;

        System.out.println("Time cost " + costTime + " 毫秒！");

        executorService.shutdown();
    }

    private static void hello1() {
        System.out.println("-hello1");
        try {
            Thread.sleep(1 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static void hello2() {
        System.out.println("--hello2");
        try {
            Thread.sleep(2 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static void hello3() {
        System.out.println("---hello3");
        try {
            Thread.sleep(3 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
